package ss.pku.Scope;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;

import ss.pku.util.GlobalContainer;

/**
 * @author liangwei
 * 
 *         Class Scope, every class has it's type declaration and map to this
 *         model
 */

public class ClassScope extends AbstractScope {

	private String className = "";
	private List modifier;
	private String extendsClass = "";
	private List<String> implementClasses;
	private TypeDeclaration type;
	private FieldDeclaration[] fields;
	private List<MethodScope> methods;

	public ClassScope(TypeDeclaration type, CompilationUnit cu) {
		System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@");
		if (type.getName() != null)
			this.className = type.getName().toString();
		this.type = type;
		this.modifier = this.type.modifiers();
		this.methods = new ArrayList<MethodScope>();
		this.fields = type.getFields();
		this.implementClasses = new ArrayList<String>();
		for (MethodDeclaration method : type.getMethods()) {
			MethodScope methodScope = new MethodScope(method, cu);
			this.methods.add(methodScope);
			// TODO set the extends and implements
			ITypeBinding binding = this.type.resolveBinding();
			ITypeBinding[] bindings;
			if (binding != null && binding.getTypeDeclaration() != null) {
				bindings = binding.getTypeDeclaration().getInterfaces();
				binding = binding.getTypeDeclaration().getSuperclass();
				if (binding !=null && binding.getPackage() != null) {
					this.extendsClass = binding.getPackage().getName() + "."
							+ binding.getName();
				}
				for (ITypeBinding itb : bindings) {
					this.implementClasses.add(itb.getPackage().getName() + "."
							+ itb.getName());
				}
			}
		}
	}

	public String getClassName() {
		return className;
	}

	public List getModifier() {
		return modifier;
	}

	public String getExtendsClass() {
		return extendsClass;
	}

	public List<String> getImplementClasses() {
		return implementClasses;
	}

	public ClassScope findExtendsClass() {
       
		SourceFileScope sourceFile = GlobalContainer.getSourceFileScope(this.extendsClass);
		ClassScope classScope = sourceFile.getClasses().get(0);
		return classScope;
	}

	public List<ClassScope> findImplementsClass() {
		List<ClassScope>   implementClassesList = null ;
		for(int i = 0; i < this.implementClasses.size(); i++){
			   String implement = this.implementClasses.get(i);
			   SourceFileScope sourceFile = GlobalContainer.getSourceFileScope(implement);
			   ClassScope classScope = sourceFile.getClasses().get(0);
			   implementClassesList.add(classScope);
		}
		return implementClassesList;
	}

	public FieldDeclaration[] getFields() {
		return fields;
	}

	public List<MethodScope> getMethods() {
		return methods;
	}

	/**
	 * get the location of this scope
	 * 
	 */
	public int getStartLocation() {
		return this.type.getStartPosition();
	}

	public int getEndLocation() {
		return this.type.getStartPosition() + this.type.getLength();
	}

	public int getLength() {
		return this.type.getLength();
	}

}
